package com.httpapi;

import android.content.Context;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

import static com.httpapi.TUtil.checkNotNull;

/**
 *  author mzw 2019-07-01 单列静态内部类,唯一，线程安全
 */
public class HttpHelper {
    private static OkHttpClient mOkHttpClient;
    private static Retrofit mRetrofit;
    private static OkHttpClient.Builder mBuilder;

    private HttpHelper() {
    }

    public OkHttpClient getOkHttpClient() {
        return mOkHttpClient;
    }

    private static class SingletonHolder{
        private static final HttpHelper INSTANCE = new HttpHelper();
    }

    public static HttpHelper api(){
        return SingletonHolder.INSTANCE;
    }

    public static void init(Context context, String baseUrl) {
        new Builder(context)
                .initOkHttp()
                .createRetrofit(baseUrl)
                .build();
    }

    public static class Builder {
        private OkHttpClient mOkHttpClient;
        private OkHttpClient.Builder mBuilder;
        private Retrofit mRetrofit;
        private Context mContext;

        public Builder(Context context) {
            this.mContext=context;
        }

        /**
         * create OkHttp 初始化OKHttpClient,设置缓存,设置超时时间,设置打印日志
         *
         * @return Builder
         */
        public Builder initOkHttp() {
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLogger());
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            if (mBuilder == null) {
                synchronized (HttpHelper.class) {
                    if (mBuilder == null) {
                        Cache cache = new Cache(new File(mContext.getCacheDir(), "QHttpCache"), 1024 * 1024 * 10);
                        mBuilder = new OkHttpClient.Builder()
                                .cache(cache)
                                .addInterceptor(interceptor)
                                .connectTimeout(30, TimeUnit.SECONDS)
                                .writeTimeout(30, TimeUnit.SECONDS)
                                .readTimeout(30, TimeUnit.SECONDS);
                    }
                }
            }

            return this;
        }

        /**
         * 程序初始化的时候添加拦截器
         *
         * @param mInterceptor Interceptor
         * @return Builder
         */
        public Builder addInterceptor(Interceptor mInterceptor) {
            checkNotNull(mInterceptor);
            this.mBuilder.addNetworkInterceptor(mInterceptor);
            return this;
        }

        /**
         * create retrofit
         *
         * @param baseUrl baseUrl
         * @return Builder
         */
        public Builder createRetrofit(String baseUrl) {
            checkNotNull(baseUrl);
            Retrofit.Builder builder = new Retrofit.Builder()
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl(baseUrl);
            this.mOkHttpClient = mBuilder.build();
            this.mRetrofit = builder.client(mOkHttpClient)
                    .build();



            return this;
        }

        public void build() {
            HttpHelper.api().build(this);
        }
    }

    // 动态添加统一请求头拦截器,调用方法 HttpHelper.api().addInterceptor(new MyInterceptor());
    public void addInterceptor(Interceptor mInterceptor) {
        if (mBuilder == null)
            return;

        checkNotNull(mInterceptor);
        this.mBuilder.addInterceptor(mInterceptor);
    }

    private void build(Builder builder) {
        checkNotNull(builder);
        checkNotNull(builder.mBuilder);
        checkNotNull(builder.mOkHttpClient);
        checkNotNull(builder.mRetrofit);
        mBuilder = builder.mBuilder;
        mOkHttpClient = builder.mOkHttpClient;
        mRetrofit = builder.mRetrofit;
    }

    public <T> T create(Class<T> clazz) {
        checkNotNull(clazz);
        checkNotNull(mRetrofit);
        return mRetrofit.create(clazz);
    }
}
